package me.zhengjie.modules.deviceposition.service.query;

import me.zhengjie.utils.PageUtil;
import me.zhengjie.modules.deviceposition.domain.DevicePosition;
import me.zhengjie.modules.deviceposition.service.dto.DevicePositionDTO;
import me.zhengjie.modules.deviceposition.repository.DevicePositionRepository;
import me.zhengjie.modules.deviceposition.service.mapper.DevicePositionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
* @author 张鹏
* @date 2019-06-05
*/
@Service
@CacheConfig(cacheNames = "devicePosition")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DevicePositionQueryService {

    @Autowired
    private DevicePositionRepository devicePositionRepository;

    @Autowired
    private DevicePositionMapper devicePositionMapper;

    /**
     * 分页
     */
    public Object queryAll(DevicePositionDTO devicePosition, Pageable pageable){
        Page<DevicePosition> page = devicePositionRepository.findAll(new Spec(devicePosition),pageable);
        return PageUtil.toPage(page.map(devicePositionMapper::toDto));
    }

    /**
    * 不分页
    */
    public Object queryAll(DevicePositionDTO devicePosition){
        return devicePositionMapper.toDto(devicePositionRepository.findAll(new Spec(devicePosition)));
    }

    class Spec implements Specification<DevicePosition> {

        private DevicePositionDTO devicePosition;

        public Spec(DevicePositionDTO devicePosition){
            this.devicePosition = devicePosition;
        }

        @Override
        public Predicate toPredicate(Root<DevicePosition> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {

            List<Predicate> list = new ArrayList<Predicate>();

            if(!ObjectUtils.isEmpty(devicePosition.getMapId())){
                /**
                * 精确
                */
                list.add(cb.equal(root.get("mapId").as(Long.class),devicePosition.getMapId()));
            }
                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
        }
    }
}